package com.digitalchina.dcn.dcss.portal.protocol;

import io.netty.buffer.ByteBuf;
import org.apache.spark.network.protocol.Encodable;

import java.nio.charset.StandardCharsets;

/**
 * Created by Administrator on 2016/8/22.
 */
public class PortalAttribute implements Encodable{

    private Type type;

    private AttributeValue value;


    public PortalAttribute(Type type, String value) {
        this.type = type;
        this.value = new StringValue(value.trim());
    }

    public PortalAttribute(Type type, byte[] valueBytes) {
        this.type = type;
        this.value = new OctetsValue(valueBytes);
    }

    public Type getType() {
        return type;
    }

    public byte[] getValue() {
        return value.getBytes();
    }

    @Override
    public int encodedLength() {
        return 2 + value.encodedLength();
    }

    @Override
    public void encode(ByteBuf buf) {
        // 写入 attribute type
        type.encode(buf);
        // 写入 attribute 长度
        buf.writeByte(encodedLength());
        // 写入 value
//        buf.writeBytes(value.getBytes(StandardCharsets.UTF_8));
        value.encode(buf);
    }

    public static PortalAttribute decode(ByteBuf buf) {
        Type type = Type.decode(buf);
        int length = buf.readByte();
        byte[] valueBytes = new byte[length - 2];
        buf.readBytes(valueBytes);
        if (isStringValue(type)) {
            return new PortalAttribute(type, new String(valueBytes, StandardCharsets.UTF_8));
        } else {
            return new PortalAttribute(type, valueBytes);
        }
    }

    private static boolean isStringValue(Type type) {
        if (type == Type.Username ||
                type == Type.Password) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("portal message attribute----------------------");
        builder.append("    attribute type:    ").append(type).append("\n");
        builder.append("    attribute value:   ").append(value).append("\n");

        builder.append("--------------------------------------------- ");

        return builder.toString();
    }

    public enum Type implements Encodable {
        Username(1), Password(2),
        Challenge(3), ChapPassword(4);

        private int id;

        Type(int id) {
            assert id < 5 : "Cannot have more than 4 attribute types";
            this.id = id;
        }

        @Override
        public int encodedLength() { return 1; }

        @Override
        public void encode(ByteBuf buf) { buf.writeByte(id); }

        public static Type decode(ByteBuf buf) {
            int id = buf.readByte();
            switch (id) {
                case 1:
                    return Username;
                case 2:
                    return Password;
                case 3:
                    return Challenge;
                case 4:
                    return ChapPassword;
                default:
                    throw new IllegalArgumentException("Unknown attribute type: " + id);
            }
        }
    }

}
